package com.topscomm.pm.quartz;

import cn.hutool.core.date.DateUnit;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.pojo.CboDeptEntity;
import com.topscomm.cbo.pojo.CboOrgEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.impl.CboDeptService;
import com.topscomm.cbo.service.impl.CboOrgService;
import com.topscomm.cbo.service.impl.CboUserService;
import com.topscomm.pm.pojo.PmTaskEntity;
import com.topscomm.pm.pojo.PmTaskLogEntity;
import com.topscomm.pm.service.impl.PmTaskLogService;
import com.topscomm.pm.service.impl.PmTaskService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.DateUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.FlowDatacodeCache;
import com.topscomm.tap.common.SessionUserBean;
import com.topscomm.tap.quartz.TapJob;
import org.apache.commons.lang3.time.DateUtils;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author: wushenghong
 * @date: 2020/6/4
 * @description: 工作日志自动生成定时任务, 每日0点执行一次符合该逻辑
 */
public class PmTaskLogSupplementApplyJob extends TapJob {
    public final static Logger logger = LoggerFactory.getLogger(PmTaskLogSupplementApplyJob.class);

    @Override
    public void run(JobExecutionContext jobExecutionContext) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" enabled=1 ");
        // 查询待补录工作日志的任务
        sql.appendSingle("and taskcategory = '{0}' and state = 9", "2");
        PmTaskService pmTaskService = (PmTaskService) SpringUtil.getBean("pmTaskService");
        List<PmTaskEntity> pmTaskEntityList = pmTaskService.queryByWhere(sql.toString());
        sql.clear();
        if (pmTaskEntityList.size() > 0) {
            for (PmTaskEntity entity : pmTaskEntityList) {
                beforeCreatTaskLog(entity);
            }
        }
    }

    /**
     * @author: wushenghong
     * @date: 2020/7/23
     * @description: 工作日志生成前判断是否已生成
     */
    public void beforeCreatTaskLog(PmTaskEntity entity) {
        PmTaskLogService pmTaskLogService = (PmTaskLogService) SpringUtil.getBean("pmTaskLogService");
        long days = cn.hutool.core.date.DateUtil.between(entity.getActualstarttime(), entity.getActualendtime(), DateUnit.DAY, false);
        long acyualDays = 0L;
        Date tempStartDate = null;
        // 遍历项目日历，计算工作日志真实时间差
        for (int i = 0; i <= days; i++) {
            tempStartDate = DateUtils.addDays(entity.getActualstarttime(), i);
            if (pmTaskLogService.isWorkDate(entity.getProjectid(), tempStartDate)) {
                acyualDays++;
            }
        }
        // 任务负责人信息
        String leaderCode = entity.getLeadercode();
        String leaderName = entity.getLeadername();
        if (leaderCode == null || leaderName == null) {
            return;
        }
        // 任务参与人信息
        String participantCodes = entity.getParticipantcodes();
        String participantNames = entity.getParticipantnames();
        List<String> participantCodeListTemp = new ArrayList<String>();
        List<String> participantNameListTemp = new ArrayList<String>();
        if (participantCodes != null && participantNames != null) {
            participantCodeListTemp = Arrays.asList(participantCodes.split(","));
            participantNameListTemp = Arrays.asList(participantNames.split(","));
        }
        //调用Arrays.asList()生产的List的add、remove方法时报异常,这样转换处理
        List<String> participantCodeList = new ArrayList<String>(participantCodeListTemp);
        List<String> participantNameList = new ArrayList<String>(participantNameListTemp);
        //任务相关人信息
        participantCodeList.add(leaderCode);
        participantNameList.add(leaderName);
        // 姓名、工号不对应则结束
        if (participantCodeList.size() != participantNameList.size()) {
            return;
        }
        // 理论日志数量与实际生成的日志数量做对比
        long taskLogSum = acyualDays * ConvertUtil.convertToLong(participantCodeList.size());
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" enabled=1 ");
        sql.appendSingle("and taskid = {0} ", entity.getId());
        List<PmTaskLogEntity> pmTaskLogEntityList = pmTaskLogService.queryByWhere(sql.toString());
        if (taskLogSum != ConvertUtil.convertToLong(pmTaskLogEntityList.size())) {
            creatTaskLog(entity,participantCodeList,participantNameList);
        }
    }

    //工作日志信息生成
    @Transactional(rollbackFor = Exception.class)
    public void creatTaskLog(PmTaskEntity entity,List<String> participantCodeList,List<String> participantNameList) {
        Map<String, Object> taskLogApplyMap = new HashMap<>();
        PmTaskLogService pmTaskLogService = (PmTaskLogService) SpringUtil.getBean("pmTaskLogService");
        FlowDatacodeCache flowDatacodeCache = (FlowDatacodeCache) SpringUtil.getBean("flowDatacodeCache");
        // 日期边界值
        Date startDate = DateUtil.getZreoOfDay(entity.getActualstarttime());
        Date endDate = DateUtil.getZreoOfDay(entity.getActualendtime());
        List<BasicEntity> entities = new ArrayList<>();
        long days = cn.hutool.core.date.DateUtil.between(startDate, endDate, DateUnit.DAY, false);
        // 循环插入
        if (days < 0) {//前端已经做过限制，这里再次验证
            return;
        }
        Map<String, Object> orgAndDeptMap = new HashMap<>();
        List<Map<String, Object>> flowidList = new ArrayList<>();
        Date tempStartDate = null;
        for (int i = 0; i < participantCodeList.size(); i++) {
            orgAndDeptMap = pmTaskLogService.queryOrgAndDeptByCode(participantCodeList.get(i));
            flowidList = flowDatacodeCache.getApprovalFlowListMap("ApprovalFlow_PmTaskLog", participantCodeList.get(i), "sortcode");
            for (int j = 0; j <= days; j++) {
                tempStartDate = DateUtils.addDays(startDate, j);
                // 避免重复插入
                StringBufferProxy sql = new StringBufferProxy();
                String tempStartDateString = cn.hutool.core.date.DateUtil.formatDate(tempStartDate);
                sql.appendSingle("taskid = {0} and finishtime = {1} and usercode = '{2}'", entity.getId(), SQLAdapter.toDateLong(tempStartDateString + " 00:00:00"), participantCodeList.get(i));
                List<PmTaskLogEntity> pmTaskLogEntityList = pmTaskLogService.queryByWhere(sql.toString());
                sql.clear();
                // 判断当前日期是否工作日且当前参与人日志未生成
                if (pmTaskLogService.isWorkDate(entity.getProjectid(), tempStartDate) && pmTaskLogEntityList.size() == 0) {
                    PmTaskLogEntity pmTaskLogEntity = new PmTaskLogEntity();
                    taskLogApplyMap.put("projectid", entity.getProjectid());
                    taskLogApplyMap.put("taskid", entity.getId());
                    taskLogApplyMap.put("name", entity.getName());
                    taskLogApplyMap.put("type", entity.getTasktype());
                    taskLogApplyMap.put("content", entity.getExplain());
                    taskLogApplyMap.put("finishtime", tempStartDate);
                    taskLogApplyMap.put("username", participantNameList.get(i));
                    taskLogApplyMap.put("usercode", participantCodeList.get(i));
                    taskLogApplyMap.put("orgcode", orgAndDeptMap.get("orgcode"));
                    taskLogApplyMap.put("orgname", orgAndDeptMap.get("orgname"));
                    taskLogApplyMap.put("deptcode", orgAndDeptMap.get("deptcode"));
                    taskLogApplyMap.put("deptname", orgAndDeptMap.get("deptname"));
                    taskLogApplyMap.put("docdate", tempStartDate);
                    taskLogApplyMap.put("flowid", flowidList.size() > 0 ? flowidList.get(0).get("id") : 0);
                    pmTaskLogEntity.convertFromMap(taskLogApplyMap);
                    entities.add(pmTaskLogEntity);
                    taskLogApplyMap.clear();
                }
            }
            orgAndDeptMap.clear();
            flowidList.clear();
        }
        // 批量插入
        if (entities.size() > 0) {
            pmTaskLogService.insertBatch(entities);
            // 系统session
            CboUserService cboUserService = (CboUserService) SpringUtil.getBean("cboUserService");
            CboDeptService cboDeptService = (CboDeptService) SpringUtil.getBean("cboDeptService");
            CboOrgService cboOrgService = (CboOrgService) SpringUtil.getBean("cboOrgService");
            List<CboUserEntity> cboUserEntities = cboUserService.queryByWhere(" code = 'QuartzUser' ");
            List<CboDeptEntity> cboDeptEntities = cboDeptService.queryByWhere(" code = 'D11803'");
            List<CboOrgEntity> cboOrgEntities = cboOrgService.queryByWhere(" code ='D1'");
            SessionUserBean sessionUserBean = new SessionUserBean();
            if (cboUserEntities.size() > 0 && cboDeptEntities.size() > 0 && cboOrgEntities.size() > 0) {
                sessionUserBean.setUser(cboUserEntities.get(0));
                sessionUserBean.setDept(cboDeptEntities.get(0));
                sessionUserBean.setWorkDept(cboDeptEntities.get(0));
                sessionUserBean.setOrg(cboOrgEntities.get(0));
                sessionUserBean.setWorkOrg(cboOrgEntities.get(0));
            }
            // 遍历提交单据
            for (BasicEntity pmTaskLogEntity : entities) {
                // 赋值单号及提交时间
                String docNo = String.valueOf(pmTaskLogEntity.getId());
                docNo = docNo.substring(0, 6) + docNo.substring(9);
                pmTaskLogEntity.setValue("docno", docNo);
                pmTaskLogEntity.setValue("submitdate", new Date());
                Map<String, Object> dataMap = pmTaskLogEntity.convertToMap();
                StringBufferProxy mailtitle = new StringBufferProxy();
                mailtitle.appendSingle("{0}的工作日志待提交，任务：{1}",
                        DateUtil.dateToString(ConvertUtil.convertToDate(dataMap.get("finishtime")), "yyyy-MM-dd"), dataMap.get("name"));
                pmTaskLogService.executeSubmit((TapEntity) pmTaskLogEntity, mailtitle.toString(), sessionUserBean);
            }
        }
    }
}
